#include "gd32_i2c.h"

//static uint32_t i2c_timeout = 0;

void i2c_config(void)
{
	rcu_periph_clock_enable(RCU_GPIOB);
	gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
	i2c_deinit(I2C0);
	/* enable I2C0 clock */
	rcu_periph_clock_enable(RCU_I2C0);
	/* configure I2C0 clock */
	i2c_clock_config(I2C0, 100000, I2C_DTCY_2);
	/* configure I2C0 address */
	i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C0_SLAVE_ADDRESS7);
	/* enable I2C0 */
	i2c_enable(I2C0);
	/* enable acknowledge */
	i2c_ack_config(I2C0, I2C_ACK_ENABLE);

#if defined(USE_I2C_1)
	/* enable I2C1 clock */
	gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);
	rcu_periph_clock_enable(RCU_I2C1);
	/* configure I2C1 clock */
	i2c_clock_config(I2C1, 100000, I2C_DTCY_2);
	/* configure I2C1 address */
	i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_SLAVE_ADDRESS7);
	/* enable I2C1 */
	i2c_enable(I2C1);
	/* enable acknowledge */
	i2c_ack_config(I2C1, I2C_ACK_ENABLE);
#endif
}

uint8_t i2c_send_byte(uint8_t slave, uint8_t reg, uint8_t dat)
{
	i2c_start_on_bus(I2C0); /* 发送一个起始位到I2C总线 */
	while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND))
		;													  /* 等待起始位发送完成 */
	i2c_master_addressing(I2C0, slave << 1, I2C_TRANSMITTER); /* 发送器件地址,写数据 */
	while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
		;									/* 等待从机地址发送完成 */
	i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); /* 清除从机地址发送完成标志位 */
	while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
		;						  /* 等待IIC发送区为空 */
	i2c_data_transmit(I2C0, reg); /* IIC发送数据，AT24C02要写入数据的地址*/
	while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
		;						  /* 等待IIC发送区为空,即发送完成 */
	i2c_data_transmit(I2C0, dat); /* IIC发送数据，AT24C02要写入的数据*/
	while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
		;				   /* 等待IIC发送区为空,即发送完成 */
	i2c_stop_on_bus(I2C0); /* 发送一个停止位到I2C总线 */
	return 1;

	// /* wait until I2C bus is idle */
	// while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY))
	// 	;
	// /* send a start condition to I2C bus */
	// i2c_start_on_bus(I2C0);
	// i2c_ack_config(I2C0, I2C_ACK_ENABLE);
	// /* wait until SBSEND bit is set */
	// while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND))
	// 	;
	// /* send slave address to I2C bus */
	// i2c_master_addressing(I2C0, slave, I2C_TRANSMITTER);
	// /* wait until ADDSEND bit is set */
	// while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
	// 	;
	// /* clear ADDSEND bit */
	// i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
	// /* wait until the transmit data buffer is empty */
	// while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
	// 	;

	// i2c_data_transmit(I2C0, reg);
	// /* wait until the TBE bit is set */
	// while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
	// 	;
	// i2c_data_transmit(I2C0, dat);
	// while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
	// 	;
	// /* send a stop condition to I2C bus */
	// i2c_stop_on_bus(I2C0);
	// while (I2C_CTL0(I2C0) & 0x0200)
	// 	;
	// i2c_ack_config(I2C0, I2C_ACK_ENABLE);
	// return 1;
}

uint8_t i2c_send_data(uint8_t slave, uint8_t reg, uint8_t *buff, uint8_t len)
{
	uint8_t i;
	/* wait until I2C bus is idle */
	while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY))
		;
	/* send a start condition to I2C bus */
	i2c_start_on_bus(I2C0);
	i2c_ack_config(I2C0, I2C_ACK_ENABLE);
	/* wait until SBSEND bit is set */
	while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND))
		;
	/* send slave address to I2C bus */
	i2c_master_addressing(I2C0, slave, I2C_TRANSMITTER);
	/* wait until ADDSEND bit is set */
	while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
		;
	/* clear ADDSEND bit */
	i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
	/* wait until the transmit data buffer is empty */
	while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
		;

	i2c_data_transmit(I2C0, reg);
	/* wait until the TBE bit is set */
	while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
		;

	for (i = 0; i < len; i++)
	{
		/* data transmission */
		i2c_data_transmit(I2C0, buff[i]);
		/* wait until the TBE bit is set */
		while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
			;
	}
	/* send a stop condition to I2C bus */
	i2c_stop_on_bus(I2C0);
	while (I2C_CTL0(I2C0) & 0x0200)
		;
	i2c_ack_config(I2C0, I2C_ACK_ENABLE);

	return 1;
}

uint8_t i2c_receive_byte(uint8_t slave, uint8_t reg)
{
	uint8_t i;
	i2c_start_on_bus(I2C0); /* 发送一个起始位到I2C总线 */
	while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND))
		;													  /* 等待起始位发送完成 */
	i2c_master_addressing(I2C0, slave << 1, I2C_TRANSMITTER); /* 发送器件地址,写数据 */
	while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
		;									/* 等待从机地址发送完成 */
	i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); /* 清除从机地址发送完成标志位 */
	while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
		;						  /* 等待IIC发送区为空 */
	i2c_data_transmit(I2C0, reg); /* IIC发送数据，AT24C02需要读出数据的地址*/
	while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
		;					/* 等待IIC发送区为空,即发送完成 */
	i2c_start_on_bus(I2C0); /* 再次发送一个起始位到I2C总线 */
	while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND))
		;												   /* 等待起始位发送完成 */
	i2c_master_addressing(I2C0, slave << 1, I2C_RECEIVER); /* 发送器件地址,读数据 */
	while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
		;									/* 等待从机地址发送完成 */
	i2c_ack_config(I2C0, I2C_ACK_DISABLE);	/* 设置为非应答 NACK, 要在清除FLAG_ADDSEND前*/
	i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); /* 清除从机地址发送完成标志位 */
	i2c_stop_on_bus(I2C0);					/* 发送一个停止位到I2C总线 */
	while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE))
		;								  /* 等待数据寄存器可读 */
	i = i2c_data_receive(I2C0);			  /* 读出接收到的数据 */
	i2c_ack_config(I2C0, I2C_ACK_ENABLE); /* 使能应答 ACK, */
	return i;
}

//uint8_t i2c_receive_data(uint8_t slave, uint8_t reg, uint8_t *buff, uint8_t len)
//{
//	uint8_t i, ret;

//	for (i = 0; i < len; i++)
//	{
//		ret = i2c_receive_byte(slave, reg + i, &buff[i]);
//	}
//	return ret;
//}
